import * as React from "react";
import Form from "rc-field-form";
import type { InternalFieldProps } from "rc-field-form/es/Field";
import type { FormInstance, NamePath } from "rc-field-form/es/interface";
import type { FC, PropsWithChildren } from "react";
import styles from "./index.module.scss";

export interface FieldProps<Values = any>
  extends Omit<InternalFieldProps<Values>, "name" | "fieldContext"> {
  name?: NamePath<Values>;
}
const { Field } = Form;

interface ErrorProps {
  warning?: boolean;
  children?: React.ReactNode[];
}

const Error: React.FC<ErrorProps> = ({ children }) => {
  return (
    <ul className={styles.error}>
      {children?.map((error: React.ReactNode, index: number) => (
        <li key={index}>{error}</li>
      ))}
    </ul>
  );
};
interface LabelFieldProps extends FieldProps {
  label?: React.ReactNode;
}
type RenderChildren<Values = any> = (
  control: any,
  meta: any,
  form: FormInstance<Values>
) => React.ReactNode;

type ChildrenType<Values = any> = RenderChildren<Values> | React.ReactNode;
type RcFieldProps<Values = any> = Omit<FieldProps<Values>, "children">;
export interface FormItemProps<Values = any> extends RcFieldProps<Values> {
  style?: React.CSSProperties;
  className?: string;
  children?: ChildrenType<Values>;
  label?: string;
  hidden?: boolean;
  addonAfter?: React.ReactNode;
  /** @deprecated No need anymore */
}
const FormItem: FC<PropsWithChildren<FormItemProps>> = ({
  name,
  label,
  children,
  style,
  hidden,
  addonAfter,
  ...restProps
}) => {
  if (!name) {
    return (
      <div className={styles.FormItem} style={style}>
        {label ? <label className={styles.label}>{label}</label> : null}
        <div style={{ display: "flex" }}>
          {children}
          {addonAfter || null}
        </div>
      </div>
    );
  }

  return (
    <div style={hidden ? { display: "none" } : { flex: 1, overflow: "hidden" }}>
      <Field name={name || null} {...restProps}>
        {(control, meta, form) => {
          const childNode =
            typeof children === "function"
              ? children(control, meta, form)
              : React.Children.map(children, (child) => {
                  if (control.value === null) control.value = undefined;
                  return React.cloneElement(child as React.ReactElement, {
                    ...control,
                  });
                });

          return (
            <div className={styles.FormItem} style={style}>
              {label ? <label className={styles.label}>{label}</label> : null}
              <div style={{ display: "flex" }}>
                {childNode}
                {addonAfter || null}
              </div>

              {meta.errors?.length ? <Error>{meta.errors}</Error> : null}
            </div>
          );
        }}
      </Field>
    </div>
  );
};

export default FormItem;
